package com.pig.aop;

import com.pig.entity.AccountLogEntity;
import com.pig.entity.AccountUserEntity;
import com.pig.service.AccountLogService;
import com.pig.service.AccountUserService;
import com.pig.utils.RequestIpUtil;
import com.pig.utils.Utils;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

/**
 * aop记录
 *
 */
@Aspect
@Component
public class LogAspect {
    @Autowired
    private AccountUserService accountUserService;

    @Autowired
    private AccountLogService accountLogService;


    @Autowired
    private AccountLogEntity accountLogEntity;
    /**
     * 用户操作记录
     */
    @Pointcut("@annotation(com.pig.aop.OperationLogger)")
    public void controllerAspect(){
        System.out.println("切入点》》》》");
    }

    @AfterReturning("controllerAspect()")
    public void doAfterReturn(JoinPoint joinPoint){
        System.out.println("==========后置通知=========");
        handleLog(joinPoint);
    }

    private void handleLog(JoinPoint joinPoint){
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            String accountName= (String) request.getSession().getAttribute("accountName");
            AccountUserEntity accountUserEntity = accountUserService.selectName(accountName);
            Integer accountId=accountUserEntity.getAccountId();

            //获取横切的方法名
            String methodName = joinPoint.getSignature().getName();
//            String methodName = signature.substring(
//                    signature.lastIndexOf(".")+1,signature.indexOf("("));
            //获取拦截的class
            String classType = joinPoint.getTarget().getClass().getName();
            //加载这个类
            Class<?> clazz = Class.forName(classType);
            //获取这个类上的方法名
            Method[] methods = clazz.getDeclaredMethods();
            System.out.println("methodName:"+methodName);
            /**
             * 循环判断，对所有方法进行循环遍历
             */
            for (Method method:methods){
                // 如果这个方法上面的注解是否含有自定义的注解
                // 并且方法名等于切点访问的方法名
                if (method.isAnnotationPresent(OperationLogger.class)
                        &&method.getName().equals(methodName)){
                    //获取method的注解
                    OperationLogger operationLogger = method.getAnnotation(OperationLogger.class);
                    //也可以用这种方式获取
                    /*Annotation[] annotations = method.getAnnotations();
                    for (Annotation annotation:annotations){
                        if (annotation instanceof OperationLogger){
                            OperationLogger operationLogger = (OperationLogger) annotation;
                        }
                    }*/
                    AccountLogEntity accountLogEntity = new AccountLogEntity();

                    accountLogEntity.setAccountId(accountId);
                    accountLogEntity.setLogIp(Utils.getIpAddress(request));
                    accountLogEntity.setLogOperation(operationLogger.option());
                    accountLogEntity.setLogContent(operationLogger.modelName());
                    accountLogService.insertAccountLog(accountLogEntity);
                }
            }
        } catch (Exception e){
            e.printStackTrace();
        }
    }


}
